#ifndef HGL_TIME_INCLUDE
#define HGL_TIME_INCLUDE

#include<hgl/type/DataType.h>
#include<hgl/TypeFunc.h>
#include<hgl/Other.h>

namespace hgl
{
	namespace io
	{
		class DataInputStream;
		class DataOutputStream;
	}//namespace io

	/**
	* 时间类，这个类用来保存和计算时间。
	*
	* 当您对Hours,Minutes,Seconds中任何一个值进行加减时，其它值都会自动计算。如：11:30这个值，使用Minutes+=55。会自动计算出55分钟后的时间，值为12:25
	*/
	class Time																											///时间类
	{
		int32 gmt_off;		///<当前时区与UTC时间的差值

		int8 hours;
		int8 minutes;
		int8 seconds;
		int32 micro_seconds;
		int8 week_day;		///<为了取这个星期过了多少秒用的

	public:

		int GetGMT			()const{return gmt_off;}																	///<取得当前时间与UTC时间的时差

		int GetHour			()const{return hours;}																		///<时
		int GetMinute		()const{return minutes;}																	///<分
		int GetSecond		()const{return seconds;}																	///<秒
		int GetMicroSecond	()const{return micro_seconds;}																///<微秒(百万分之一秒)

		int GetDaySeconds	()const{return (hours*HGL_TIME_ONE_HOUR)+(minutes*HGL_TIME_ONE_MINUTE)+seconds;}			///<今天过了多少秒

		int GetWeekSeconds	()const																						///<这个星期过了多少秒
		{
			int week = week_day;
			if(week_day > 0)
				--week;

			if(week_day == 0)
				week=(HGL_DAY_ONE_WEEK-1);

			return ((week*HGL_HOUR_ONE_DAY+hours)*HGL_TIME_ONE_HOUR)+(minutes*HGL_TIME_ONE_MINUTE)+seconds;
		}

// 		int GetPastWeekSeconds()const{return int(GetDoubleTime()-GetWeekSeconds());}									///<过去那些年到这周一0点过了多少秒

		void SetGMT(int go){gmt_off=go;}
		void SetHour(int);
		void SetMinute(int);
		void SetSecond(int);
		void SetMicroSecond(int);

	public:

		Time();
		Time(const double);
		Time(int,int,int,int);
		Time(const Time &);

		void Clear()
		{
			gmt_off=0;
			hours=0;
			minutes=0;
			seconds=0;
			micro_seconds=0;
			week_day=0;
		}

		void Set(int h,int m=0,int s=0,int ms=0,int wd=0);

		Time &operator = (const Time &);

		const int Comp(const Time &)const;

		CompOperator(const Time &,Comp);

		void Sync(const double=0);																	///<和系统时间同步

		bool SaveToStream(io::DataOutputStream *) const;
		bool LoadFromStream(io::DataInputStream *);
	};//class Time

	/**
	* 日期类，这个类用来保存和计算日期。带有闰年的处理
	*
	* 当您对Year,Month,Day中任意一个值进行修改时，其它值都会自动跟着计算。如1981-4-17,如果使用Day+=400，会自动计算出400天之后的日期，结果是1982-5-21
	*/
	class Date																						///日期类
	{
		int32 year;
		int8 month;
		int8 day;

		int8 week_day;
		int16 year_day;

		int8 max_days_per_month;

	public:

		int GetYear		()const{return year;}														///<年
		int GetMonth	()const{return month;}														///<月
		int GetDay		()const{return day;}														///<日
		int GetMaxDays	()const{return max_days_per_month;}													///<本月天数
		int GetWeekDay	()const{return week_day;}													///<星期,0为星期天
		int GetYearDay	()const{return year_day;}													///<今天为这一年的第几天

		void SetYear	(int y){year=y;}
		void SetMonth	(int);
		void SetDay		(int);

	public:

		Date();
		Date(const double);
		Date(int,int,int);
		Date(const Date &);

		void Clear()
		{
			year=0;
			month=0;
			day=0;

			week_day=0;
			year_day=0;

			max_days_per_month=0;
		}

		void Set(int y,int m,int d,int wd=0,int yd=0);

		Date &operator = (const Date &);

		const int Comp(const Date &)const;

		CompOperator(const Date &,Comp);

		void Sync(const double=0);																	///<和系统日期同步

		bool SaveToStream(io::DataOutputStream *) const;
		bool LoadFromStream(io::DataInputStream *);
	};//class Date

	/**
	 * 根据当前时间，转换出Date/Time两个结构
	 */
	void ToDateTime(Date &,Time &,const double cur_time=0);

	/**
	 * 根据日期和时间，转换出以秒为单位的时间值
	 * @param year 年
	 * @param month 月
	 * @param day 日
	 * @param hour 小时
	 * @param minute 分
	 * @param second 秒
	 * @param micro_second 微秒(1/1000秒)
	 * @return 转换出的值
	 */
	double FromDateTime(const int year,const int month,const int day,
						const int hour,const int minute=0,const int second=0,const int micro_second=0,const int gmt_off=0);

	/**
	 * 根据Date/Time转换出以秒为单位的时间值
	 */
	double FromDateTime(const Date &,const Time &);
}//namespace hgl
#endif//HGL_TIME_INCLUDE
